package com.yonyou.brigade.third_parties.huazhu.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.props.PropUtil;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.basic_init.service.IUserCenterService;
import com.yonyou.brigade.order_center.model.ThirdResult;
import com.yonyou.brigade.third_parties.huazhu.constant.HZConstant;
import com.yonyou.brigade.third_parties.huazhu.dao.HzUserMapper;
import com.yonyou.brigade.third_parties.huazhu.model.HzUser;
import com.yonyou.brigade.third_parties.huazhu.service.IHzPublicService;
import com.yonyou.brigade.third_parties.huazhu.service.IHzUserService;
import com.yonyou.brigade.util.HttpClientUtil;
import com.yonyou.brigade.util.operateutil.AESUtil4ECB;
import com.yonyou.brigade.util.operateutil.CompareUtils;
import com.yonyou.ybzboot.starter.common.util.StringUtil;
import com.yonyou.ybzboot.starter.common.util.UrlUtil;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author houyb
 * @since 2020-06-18
 */
@Service
public class HzUserServiceImpl extends ServiceImpl<HzUserMapper, HzUser> implements IHzUserService {

    @Value("${huazhu.baseUrl}")
    private String baseUrl;

    @Autowired
    private IHzPublicService hzPublicService;

    @Autowired
    private IBriChannelService briChannelService;

    @Autowired
    private IUserCenterService userCenterService;

    @Autowired
    private IHzUserService hzUserService;

    @Autowired
    private PropUtil propUtil;

    @Value("${huazhu.password}")
    private String password;

    private static Logger logger = LoggerFactory.getLogger(HzUserServiceImpl.class);

    private static final String[] compareFields = {"personCode", "phone", "valid", "employeeName"};


    public void syncUser(String tenant, String phone, UcUserDto ucUserDto, BriChannel briChannel){
        HzUser hzUser = ucUserConvert2HzUser(ucUserDto, tenant);
        Wrapper<HzUser> wrapper = new EntityWrapper<>();
        wrapper.eq(HzUser.TENANT, tenant);
        wrapper.eq(HzUser.PHONE, phone);
        List<HzUser> hzUserList = hzUserService.selectList(wrapper);

        //判断是否已经同步过，新增或修改
        if (hzUserList != null && hzUserList.size() > 0){
            //如果已经同步过，检查信息是否有变化，如果有变化则更新
            Map<String, String> compareMap = new HashMap<>();

            if (compareFields != null && compareFields.length > 0) {
                for (int i = 0; i < compareFields.length; i++) {
                    //此处只需要key值
                    compareMap.put(compareFields[i], "");
                }
            }
            Map<String, Object> compareResult = CompareUtils.getModifyContent(hzUserList.get(0), hzUser, compareMap);
            if (compareResult != null && compareResult.size() > 0) {
                //更新已经同步过的用户信息或删除
                String operationType = "1".equals(hzUser.getValid()) ? HZConstant.REGISTER_OPERATION_TYPE_ALTER : HZConstant.REGISTER_OPERATION_TYPE_DELETE;
                ThirdResult thirdResult = this.syncUser(hzUser, briChannel, operationType);
                if (thirdResult.getSuccess()){
                    hzUser.setId(hzUserList.get(0).getId());
                    this.baseMapper.updateById(hzUser);
                }
            }
        }else {
            //未同步过，新增或删除
            String operationType = "1".equals(hzUser.getValid()) ? HZConstant.REGISTER_OPERATION_TYPE_ADD : HZConstant.REGISTER_OPERATION_TYPE_DELETE;
            ThirdResult thirdResult = this.syncUser(hzUser, briChannel, operationType);
            if (thirdResult.getSuccess()){
                this.baseMapper.insert(hzUser);
            }
        }
    }

    @Override
    public ThirdResult syncUser(HzUser hzUser, BriChannel briChannel, String operationType) {
        JSONObject config = JSONObject.parseObject(briChannel.getConfig());
        String srcID = config.getString("srcID");
        String vCard = config.getString("vCard");
        String url = config.getString("baseUrl");
        if (StringUtil.isEmpty(url)){
            url = baseUrl + HZConstant.REGISTER_URL_PATH;
        }else {
            url = url + HZConstant.REGISTER_URL_PATH;
        }
        String token = hzPublicService.getToken();

        JSONObject requestParam = convertRequestParam(hzUser, srcID, vCard, operationType, token);
        String psd = config.getString("password");
        if (StringUtil.isNotEmpty(psd)){
            token = hzPublicService.getToken(psd);
            requestParam = convertRequestParam(hzUser, srcID, vCard, operationType, token, psd);
        }
        logger.info("同步华住酒店用户" + requestParam.toJSONString());
        String strResult = HttpClientUtil.doPostJson(url, requestParam.toJSONString());
        logger.info("同步华住酒店用户结果" + strResult);
        if (StringUtil.isNotEmpty(strResult)){
            JSONObject rs = JSONObject.parseObject(strResult);
            if ("1".equals(rs.getString("ResCode"))){
                return new ThirdResult(true, rs.getString("ResDesc") );
            }else {
                return new ThirdResult(false, rs.getString("ResDesc") );
            }
        }
        return new ThirdResult(false, strResult );
    }

    @Override
    public void syncUserList(List<UcUserDto> ucUserDto, BriChannel briChannel, String tenant) {
        for (UcUserDto userDto : ucUserDto) {
            syncUser(tenant, userDto.getPhone(), userDto, briChannel);
        }
    }

    @Override
    public String loginUrl(String tenant, String org, String phone, String pageType, String pcOrH5, String jsonExt) {
        BriChannel briChannel = briChannelService.getEnableChannelByOpenType(tenant, HZConstant.CHANNEL, 1);
        if(briChannel==null) {
            //没有开通华住酒店
            return propUtil.getNO_ACCESS_URL();
        }
        UcUserDto ucUser = userCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        if (ucUser == null){
            return propUtil.getNO_ACCESS_URL();
        }
        //同步用户
        if (1 == briChannel.getSyncUser()){
            syncUser(tenant, phone, ucUser, briChannel);
        }

        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JSONObject config = JSONObject.parseObject(briChannel.getConfig());
        String  srcID = config.getString("srcID");
        String vCard = config.getString("vCard");
        String time = sf.format(new Date());

        String travelType = AESUtil4ECB.encryptUtf8("YS", password);
        String uniqueId = AESUtil4ECB.encryptUtf8(ucUser.getPersonCode(), password);
        String occupantNumber = AESUtil4ECB.encryptUtf8(ucUser.getPersonCode(), password);

        String secretString = hzPublicService.getSecretString(time, srcID, vCard);
        String token  = hzPublicService.getToken();
        String psd = config.getString("password");
        if (StringUtil.isNotEmpty(psd)){

            token = hzPublicService.getToken(psd);
            secretString = hzPublicService.getSecretString(time, srcID, vCard, psd);
            travelType = AESUtil4ECB.encryptUtf8("YS", psd);
            uniqueId = AESUtil4ECB.encryptUtf8(ucUser.getPersonCode(), psd);
            occupantNumber = AESUtil4ECB.encryptUtf8(ucUser.getPersonCode(), psd);
        }


        String url = config.getString("baseUrl");
        if (StringUtil.isEmpty(url)){
            url = baseUrl;
        }
        StringBuilder paramBuilder = new StringBuilder();
        paramBuilder.append("SrcID=");
        paramBuilder.append(srcID);
        paramBuilder.append("&Time=");
        paramBuilder.append(UrlUtil.getURLEncoderString(time));
        paramBuilder.append("&SecretString=");
        paramBuilder.append(secretString);
        paramBuilder.append("&VCard=");
        paramBuilder.append(vCard);
        paramBuilder.append("&UniqueId=");
        paramBuilder.append(uniqueId);
        paramBuilder.append("&TravelType=");
        paramBuilder.append(travelType);
        paramBuilder.append("&OccupantNumber=");
        paramBuilder.append(occupantNumber);
        paramBuilder.append("&Token=");
        paramBuilder.append(token);
        return url + "?" + paramBuilder.toString();
    }


    /**
     * 拼装请求参数
     * @param hzUser
     * @param srcID
     * @param vCard
     * @param operationType
     * @param token
     * @return
     */
    private JSONObject convertRequestParam(HzUser hzUser, String srcID, String vCard, String operationType, String token){
        return convertRequestParam(hzUser, srcID, vCard, operationType, token, password);
    }
    /**
     * 拼装请求参数
     * @param hzUser
     * @param srcID
     * @param vCard
     * @param operationType
     * @param token
     * @param psd
     * @return
     */
    private JSONObject convertRequestParam(HzUser hzUser, String srcID, String vCard, String operationType, String token, String psd){
        JSONObject param = new JSONObject();
        param.put("SrcID", srcID);
        param.put("VCard", vCard);
        param.put("UniqueId", AESUtil4ECB.encryptUtf8(hzUser.getPersonCode(), psd));
        param.put("EmployeeName", AESUtil4ECB.encryptUtf8(hzUser.getEmployeeName(), psd));
//        param.put("CertificatesType","C01" );
//        param.put("CertificatesNumber",  AESUtil4ECB.encryptUtf8("110101199003072412", psd));
        param.put("Mobile", AESUtil4ECB.encryptUtf8(hzUser.getPhone(), psd));
        param.put("OperationType", operationType);
        param.put("token", token);
        return param;
    }

    @Override
    public HzUser ucUserConvert2HzUser(UcUserDto ucUserDto, String tenant){
        HzUser hzUser = new HzUser();
        hzUser.setPersonCode(ucUserDto.getPersonCode());
        hzUser.setPhone(ucUserDto.getPhone());
        hzUser.setEmployeeName(ucUserDto.getUserName());
        hzUser.setTenant(tenant);
        hzUser.setCertificatesType("");
        hzUser.setCertificatesNumber("");
        String valid = ucUserDto.getValid() != null ? ucUserDto.getValid().toString() : "0";
        hzUser.setValid(valid);
        return hzUser;
    }

    @Override
    public List<HzUser> ucUserConvert2HzUser(List<UcUserDto> ucUserDto, String tenant) {
        List<HzUser> resultList = new ArrayList<>();
        for (UcUserDto userDto : ucUserDto) {
            HzUser hzUser = ucUserConvert2HzUser(userDto, tenant);
            resultList.add(hzUser);
        }
        return resultList;
    }
}
